撰寫單元測試,速度更快 !
工程師的日常,是不斷的與程式錯誤(Bug) 進行搏鬥
是工程師的「美德」,也是工程師的痛苦來源 :
撰寫「單元測試」- 使用程式來測試程式,只是要多花了一點時間。
如果正確使用「單元測試」的方法 :
甚至會比不寫測試的開發流程,開發的更加快速 !
傳統開發上的單元測試流程,會先寫產品程式,在寫測試程式。
如果產品程式已經完成了,在 UI 介面上都沒有測出問題來。
怠惰之心,人皆有之。
工程師,可能會直接略過這一段。
即便是團隊要求,當任務時程緊急的時候,還是會有很大的概率,會被省略。
這兩本書籍,相同作者,但不同主題。
書中都提到 :
測試驅動開發 (Test Driven Development , TDD)
藉由先撰寫「測試」的程式碼 ,「驅動」產品程式的「開發」。
因為有各種的優點,章節的結論就是直接認定 :
「 TDD 是專業人士的選擇 」
不使用 TDD 的程式設計師,只能代表:
可能還「 不夠專業 」
測試驅動開發,有三大法則 :
在撰寫一個單元測試前,不可撰寫任何產品程式
要先從測試程式開始撰寫,絕對不要先撰寫產品程式。
「順序」非常重要
只撰寫剛好無法通過的單元測試,不能編譯也算無法通過
撰寫的測試程式,結果必須是失敗的,而且是「剛好」失敗的。
「不要一次完成所有的測試程式」
只撰寫剛好能通過當前測試失敗的產品程式
撰寫的產品程式,結果必須是成功的,而且是「剛好」成功的。
「先完成一個小目標」
然後,依據這個法則,大約 每 30 秒就會執行一次程式碼:
如此就會構成一個循環,不斷重複。測試的程式碼與產品的程式碼就會同步增長並且互相匹配。
相比於傳統開發上的單元測試流程,割裂的兩個動作就會合而為一 :
測試就是開發,開發就是測試。
因為兩個動作,是在同一時間被撰寫出的,速度肯定是比分開兩步驟執行的更快 !
但為什麼會比不寫單元測試的開發流程,還要更快 ?
關鍵點在於 :
「極短的程式碼執行週期」
「trial and error」 (嘗試錯誤的方法),在極短的時間內,以極高的頻率,高速運作。
修正與反饋組合成的節奏,就像鋼琴樂譜一樣 ,優美且流暢的彈奏出來。
依據 TDD 三大法則開發的程式,就會帶來五大好處 :
依據這個法則,就會撰寫非常多的測試程式,並且測試程式相比於產品程式,只會多不會少。
程式修改後,執行「單元測試」的綠燈,會非常的確定,程式與當初開發的預期結果
是一致的
「缺陷注入率」指的是出現錯誤缺陷的比率,原因相似於「確定性」。
越低的錯誤率,維護程式的成本就會越小,也會是每個開發者追求的目標。
「勇氣」指的是面對糟糕程式碼的「勇氣」
面對糟糕的程式碼,你會想要改它,但又怕會把它改壞。
但若這個程式 有遵循 TDD 的法則,你隨時都會有個安全機制 :
提醒你程式改壞,還是程式改好
因為你不在害怕,你就會開始動手整理,而不會:
「放任程式碼劣化而視若無睹」
在使用第三方的框架時,可以使用 TDD 來測試程式的行為
這種用「單元測試」堆砌起來的範例,就會是一種比「使用手冊」,更好的「文件」。
因為,這個「文件」,是用程式碼實際描述的,你會更加清楚,每一個涵式與參數的用途。
當有新的版本時:
執行一次單元測試,能很快地發現不一樣的地方。
由於 TDD 的流程,使得「產品程式」不會制約「測試程式」
但「測試程式」卻能制約「產品程式」
它會逼迫你在撰寫「產品程式」時,必須要將函式與其它函式進行解耦合,才能通過測試的要求。
無形中,會讓你去思考:
「如何設計」
這邊使用 IntelliJ 加上 Java 單元測試的 JUnit 框架簡單示範
現在假定,要開發 Domain 層的一個服務 :
服務名稱叫 AppInfoService
實作的功能 :
判定應用程式的版本,是不是最新的
依據這個法則,稍微變通一下。先創建「服務介面」與「實作類別」:
AppInfoServiceinterface
AppInfoServiceImplclass
AppInfoService
AppInfoServiceImplimplements
只做這些,應該還不會偏離法則太遠
(IntelliJ 快捷鍵 : cmd + shift + T )
單元測試失敗
(IntelliJ 快捷鍵 : control + shift + R )
撰寫產品程式
單元測試成功
(IntelliJ 快捷鍵 : control + shift + R )
如此,就完成了一個循環,後續如果還有更複雜的功能。也是透過這種循環快速開發。
JUnit 是 Java 的 單元測試框架,其他的程式語言也有各自的測試框架。
例如:
這三個是我有用過,並且稍微整理成一個專案的:
測試驅動開發的三大法則,是不是覺得字有點多難以記住。
你可以簡單的精簡為 :
先測試,後程式
這個思維模式,讓我想到 「文件」(開發文件),也是一個很重要的東西。
那麼,程式開發的流程是不是也可以變成 :
文件 > 測試 > 程式
如此的順序執行呢? (我還在研究的問題...)
測試驅動開發,只是個簡單的思維轉變,就能夠帶來如此巨大的力量。
當你的主管發現你,開發的速度超快,錯誤率又超低的時候。
你可以跟他說 :
這個就是「違反直覺」的力量
其他還有更多「違反直覺」的事情 :
「休息是為了走更長遠的路」(需要更多的放風時間 !)
「安靜是種力量」(PM/SA 沒事,不要那麼常跑來找我 | 你說越多,我可能會開發的越慢 !)
拆牆容易,砌牆難
-- Gamma Ray Studio